package sw6.visualschedule.activitylist;

import sw6.visualschedule.extendedViews.LinkedActivityView;

import android.content.Context;
import android.graphics.Rect;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.TranslateAnimation;
import android.widget.ImageView;

import java.util.Date;

/**
 * 
 * @author kfuglsang
 *
 */
public class ActivityImageViewTouchListener implements OnTouchListener {

	private final AnimationListener aniListener = new AnimationListener() {
		
		@Override
		public void onAnimationEnd(final Animation animation) {
			isAnimating = false;
			mDraggableImage.setVisibility(View.INVISIBLE);
			mActivityView.setVisibility(View.VISIBLE);					
			if (mActivityView.getScheduleActivity().getInstanceDate().before(new Date())) {
				mActivityView.startAnimation();				
			}
		}
		
		@Override
		public void onAnimationRepeat(final Animation animation) {
			
		}
		
		@Override
		public void onAnimationStart(final Animation animation) {
			isAnimating = true;
		}
	};
	private Boolean isAnimating = false;
	private transient boolean isOnTopOfTargetView = false;
	private transient StartActivityListener mActivityListener;
	private final transient LinkedActivityView mActivityView;
	private final transient ImageView mDraggableImage;
	
	private transient Rect mHitRect;
	
	/**
	 * Initializes the ActivityImageViewTouchListener.
	 * 
	 * WARNING: High coupling with ActivityList. Should not be used by any other classes than that
	 * 
	 * @param  context the context in which the listener should run.
	 * @param  activityView    the LinkedActivityView to listen for events on. 
	 * @param  outerContainerView  the draggable image.
	 */	
	public ActivityImageViewTouchListener(Context context, LinkedActivityView activityView, ImageView drag) {
		mActivityView = activityView;
		mDraggableImage = drag;
	}
	
	/**
	 * Handles on touch events on a view.
	 * 
	 * @param  view    the view being touched
	 * @param  event   the event that has occurred.
	 * 
	 * @return true if the event is handled by the method.
	 */
	@Override
    public boolean onTouch(final View view, final MotionEvent event) {
    	Boolean droppedOnActiveZone;

    	if (isAnimating)
			return false;
		
    	switch (event.getActionMasked())
        {
            case MotionEvent.ACTION_MOVE:
            	//Move the image to the position underneith user's finger, by modifying padding.
            	//TODO: To avoid unnesceary image manipulation, extend ImageView to hold these values.
            	mDraggableImage.setPadding((int) event.getRawX()
                        - (mDraggableImage.getDrawable().getMinimumWidth() / 2),
                        (int) event.getRawY()
                                - (int) (mDraggableImage.getDrawable().getMinimumHeight() / 2),
                        0, 0);                    

                //Is the dragging image on top of the target view?
            	droppedOnActiveZone = mHitRect.contains((int) event.getRawX(),(int) event.getRawY());
                
            	//Avoid constantly setting the drawable by comparing the found boolean to a boolean value
            	//that is changed every time droppedOnActiveZone changes.
            	if (droppedOnActiveZone != isOnTopOfTargetView) {
            		isOnTopOfTargetView = droppedOnActiveZone;
            		if (droppedOnActiveZone)
            			mActivityListener.draggableImageOverTarget();
            		else
            			mActivityListener.draggableImageAwayFromTarget();
            	}
            		
                break;

            case MotionEvent.ACTION_UP:

            	mActivityListener.up();

                //Is the dragging view dropped on the drop zone (target view)
                droppedOnActiveZone = mHitRect.contains((int) event.getRawX(), (int) event.getRawY());
                
                if (droppedOnActiveZone) {
                    //User has dragged activity to dropzone. Check if the step view or countdown view should be shown.
                	//TODO : mCurrentActivity global?
					mActivityListener.draggableImageDroppedOnTarget();
                } else {
                    //Hide target view (dropzone)
                	mActivityView.getLinkedImageView().setVisibility(View.INVISIBLE);
                    
                    //Create animation that moves activity back to initial position.
                	final int paddingLeft = mDraggableImage.getPaddingLeft();
                    final int paddingTop = mDraggableImage.getPaddingTop();
                    
                    final Rect rectangle = new Rect();
                    view.getHitRect(rectangle);
                    final int[] pos = new int[2];
                    mActivityView.getLocationOnScreen(pos);
                    
                    final int toX = pos[0];
                    final int toY = pos[1];
                    mDraggableImage.setPadding(0, 0, 0, 0);
                    
                    final TranslateAnimation anim = new TranslateAnimation(Animation.ABSOLUTE, paddingLeft, Animation.ABSOLUTE, toX , Animation.ABSOLUTE, paddingTop, Animation.ABSOLUTE, toY);                    
                    anim.setZAdjustment(Animation.ZORDER_TOP);
                    
                    anim.setDuration(500);                    
                    anim.setAnimationListener(aniListener);
                    
                    mDraggableImage.setPadding(0, 0, 0, 0);                    
                    mDraggableImage.startAnimation(anim);
                }

                break;
            case MotionEvent.ACTION_DOWN:            	
            	final int[] location = new int[2];
            	mActivityView.getLinkedImageView().getLocationOnScreen(location);        	
            	mHitRect = new Rect(location[0], location[1], location[0] + mActivityView.getLinkedImageView().getWidth(), location[1] + mActivityView.getHeight());
            	              
            	mDraggableImage.setPadding((int) event.getRawX()
                        - (mDraggableImage.getDrawable().getMinimumWidth() / 2),
                        (int) event.getRawY()
                                - (int) (mDraggableImage.getDrawable().getMinimumHeight() / 2),
                        0, 0);    
            	
            	mActivityView.getLinkedImageView().setVisibility(View.VISIBLE);            	
                mActivityListener.down();      
                              
                
                break;
                
            default:
                break;
        }

        return true;
    }
	
	public void setActivityListener(StartActivityListener activityListener) {
		mActivityListener = activityListener;
	}
}
